bitkeeper revision 1.339.1.11 (3f132035CGTz70qQug_kGM8wm0k5gw)
authorkaf24@scramble.cl.cam.ac.uk <kaf24@scramble.cl.cam.ac.uk>
Mon, 14 Jul 2003 21:27:17 +0000 (21:27 +0000)
committerkaf24@scramble.cl.cam.ac.uk <kaf24@scramble.cl.cam.ac.uk>
Mon, 14 Jul 2003 21:27:17 +0000 (21:27 +0000)
dev.c, xen_block.c, kernel.c, setup.c, nmi.c:
  Fixed deadlock race in network code. Watchdog timer is now disabled by default. Improved tracing in Xen blkdev code.

xen/arch/i386/nmi.c
xen/arch/i386/setup.c
xen/common/kernel.c
xen/drivers/block/xen_block.c
xen/net/dev.c

index 23fd691fe1d6906907f3203999aefbc66433a117..f48efb232220888a1aa517019a41ce7c54a1ed9e 100644 (file)
 #include <asm/msr.h>
 #include <asm/mpspec.h>
 
-#undef Dprintk
-#define Dprintk(x...) printk(x)
-
-unsigned int nmi_watchdog = NMI_LOCAL_APIC;
+unsigned int nmi_watchdog = NMI_NONE;
 static unsigned int nmi_hz = HZ;
 unsigned int nmi_perfctr_msr;  /* the MSR to reset in NMI handler */
 extern void show_registers(struct pt_regs *regs);
@@ -80,6 +77,9 @@ int __init check_nmi_watchdog (void)
     unsigned int prev_nmi_count[NR_CPUS];
     int j, cpu;
     
+    if (!nmi_watchdog)
+        return 0;
+
     printk("testing NMI watchdog ---\n");
 
     for (j = 0; j < smp_num_cpus; j++) {
@@ -197,6 +197,9 @@ static int __pminit setup_p4_watchdog(void)
 
 void __pminit setup_apic_nmi_watchdog (void)
 {
+    if (!nmi_watchdog)
+        return;
+
     switch (boot_cpu_data.x86_vendor) {
     case X86_VENDOR_AMD:
         if (boot_cpu_data.x86 != 6 && boot_cpu_data.x86 != 15)
index 1372c7b403d20399aba93ce186f590ad021c91a7..1e3695f8471d26c1adda77540b6047324caa63b9 100644 (file)
@@ -286,17 +286,20 @@ void __init start_of_day(void)
     extern void tqueue_bh(void);
     extern void immediate_bh(void);
     extern void init_timervecs(void);
-       extern void disable_pit(void);
-       extern void ac_timer_init(void);
+    extern void disable_pit(void);
+    extern void ac_timer_init(void);
     extern int  setup_network_devices(void);
     extern void net_init(void);
     extern void initialize_block_io(void);
     extern void initialize_keytable(); 
     extern void initialize_serial(void);
     extern void initialize_keyboard(void);
-    extern int opt_nosmp;
+    extern int opt_nosmp, opt_watchdog;
     unsigned long low_mem_size;
     
+    if ( opt_watchdog ) 
+        nmi_watchdog = NMI_LOCAL_APIC;
+
     /*
      * We do this early, but tables are in the lowest 1MB (usually
      * 0xfe000-0xfffff). Therefore they're unlikely to ever get clobbered.
index 999c88fd4bd517ae466cd28f6d5221a728de7600..896dd8e735b0aa807ae9b010e1b6f545d33cb057 100644 (file)
@@ -41,7 +41,7 @@ unsigned int opt_ser_baud = 9600;  /* default baud for COM1 */
 unsigned int opt_dom0_mem = 16000; /* default kbytes for DOM0 */
 unsigned int opt_ne_base = 0; /* NE2k NICs cannot be probed */
 unsigned char opt_ifname[10] = "eth0";
-int opt_noht=0, opt_noacpi=0, opt_nosmp=0;
+int opt_noht=0, opt_noacpi=0, opt_nosmp=0, opt_watchdog=0;
 enum { OPT_IP, OPT_STR, OPT_UINT, OPT_BOOL };
 static struct {
     unsigned char *name;
@@ -56,6 +56,7 @@ static struct {
     { "noht",        OPT_BOOL, &opt_noht },
     { "noacpi",      OPT_BOOL, &opt_noacpi },
     { "nosmp",       OPT_BOOL, &opt_nosmp },
+    { "watchdog",    OPT_BOOL, &opt_watchdog },
     { NULL,       0,        NULL     }
 };
 
index 644f91254d6b5b20dd298958761c61068ebfabb9..369cbfe463633649a1fecf1168856791bcfaa1ad 100644 (file)
@@ -704,14 +704,14 @@ static void dispatch_rw_block_io(struct task_struct *p, int index)
             phys_seg[nr_psegs].nr_sects      = nr_sects;
            if (p->domain != 0 &&
                !xen_physdisk_access_okay(&phys_seg[nr_psegs], p, operation)) {
-             DPRINTK("access denied\n");
-             /* XXX not quite right, but close enough. */
-             goto bad_descriptor;
+                DPRINTK("access denied: dev=%04x off=%ld nr=%ld\n",
+                        req->device, req->sector_number + tot_sects, nr_sects);
+                goto bad_descriptor;
            }
            phys_seg[nr_psegs].dev           = xendev_to_physdev(req->device);
             if ( phys_seg[nr_psegs].dev == 0 ) 
            {
-               DPRINTK("bad device\n");
+               DPRINTK("bad device: %04x\n", req_device);
                goto bad_descriptor;
            }
             new_segs = 1;
index 471b0ae5c56a37acbe425ab764c88fe6b98e9580..f1ce37cf928f96da513113e92ae77a1af80a1e02 100644 (file)
@@ -1768,7 +1768,7 @@ long do_net_update(void)
     net_vif_t *vif;
     net_idx_t *shared_idxs;
     unsigned int i, j, idx;
-    struct sk_buff *skb;
+    struct sk_buff *skb, *interdom_skb = NULL;
     tx_req_entry_t tx;
     rx_req_entry_t rx;
     unsigned long pte_pfn, buf_pfn;
@@ -1889,7 +1889,11 @@ long do_net_update(void)
                 skb->len = tx.size - ETH_HLEN;
                 unmap_domain_mem(skb->head);
 
-                (void)netif_rx(skb);
+                /*
+                 * We must defer netif_rx until we have released the current
+                 * domain's page_lock, or we may deadlock on SMP.
+                 */
+                interdom_skb = skb;
 
                 make_tx_response(vif, tx.id, RING_STATUS_OK);
             }
@@ -1897,6 +1901,11 @@ long do_net_update(void)
         tx_unmap_and_continue:
             unmap_domain_mem(g_data);
             spin_unlock_irq(&current->page_lock);
+            if ( interdom_skb != NULL )
+            {
+                (void)netif_rx(interdom_skb);
+                interdom_skb = NULL;
+            }
         }
 
         vif->tx_req_cons = i;